package algorithm.sort;

import java.util.Arrays;

/**交换类排序法
 * 快速排序
 *
 *          基本思想：
 * 快速排序是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。
 * 它的基本思想是：通过一趟排序将要排序的数据分割成独立的两部分，
 * 其中一部分的所有数据都比另外一部分的所有数据都要小，然后再按此方法对这两部分数据分别进行快速排序，
 * 整个排序过程可以递归进行，以此达到整个数据变成有序序列。
 *
 *          实现：
 * 设要排序的数组是A[0]……A[N-1]，首先任意选取一个数据（通常选用第一个数据）作为关键数据，
 * 然后将所有比它小的数都放到它前面，所有比它大的数都放到它后面，这个过程称为一趟快速排序。
 * 值得注意的是，快速排序不是一种稳定的排序算法，也就是说，多个相同的值的相对位置也许会在算法结束时产生变动。
 *  一趟快速排序的算法是：
 * 1）设置两个变量i、j，排序开始的时候：i=0，j=N-1；
 * 2）以第一个数组元素作为关键数据，赋值给key，即 key=A[0]；
 * 3）从j开始向前搜索，即由后开始向前搜索（j -- ），找到第一个小于key的值A[j]，A[i]与A[j]交换；
 * 4）从i开始向后搜索，即由前开始向后搜索（i ++ ），找到第一个大于key的A[i]，A[i]与A[j]交换；
 * 5）重复第3、4、5步，直到 I=J； (3,4步是在程序中没找到时候j=j-1，i=i+1，直至找到为止。
 * 找到并交换的时候i， j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后令循环结束。）
 *          举例说明：
// 如无序数组[6 2 4 1 5 9]
 * a),先把第一项[6]取出来,
 * 用[6]依次与其余项进行比较,
 * 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边
 * 如果比[6]大就放[6]后边,9比[6]大,放到[6]后边, *6出列后大喝一声,比我小的站前边,比我大的站后边,行动吧!霸气十足~
 * 一趟排完后变成下边这样:
 * 排序前 6 2 4 1 5 9
 * 排序后 2 4 1 5 6 9
 *
 * b),对前半拉[2 4 1 5]继续进行快速排序
 * 重复步骤a)后变成下边这样:
 * 排序前 2 4 1 5
 * 排序后 1 2 4 5
 * 前半拉排序完成,总的排序也完成:
 * 排序前:[6 2 4 1 5 9]
 * 排序后:[1 2 4 5 6 9]
 * Created by wow on 2016/11/8.
 *
 * 快速排序时间复杂度O(nlogn)最好时间O(nlogn)最坏时间O(n2)
 * 空间复杂度O(logn),使用递归
 */
public class QuickSort {
    public static void sort(int a[], int low, int hight) {
        int i, j, index;
        if (low > hight) {
            return;
        }
        i = low;
        j = hight;
        index = a[i]; // 用子表的第一个记录做基准
        while (i < j) { // 从表的两端交替向中间扫描
            while (i < j && a[j] >= index)
                j--;
            if (i < j)
                a[i++] = a[j];// 用比基准小的记录替换低位记录
            while (i < j && a[i] < index)
                i++;
            if (i < j) // 用比基准大的记录替换高位记录
                a[j--] = a[i];
        }
        a[i] = index;// 将基准数值替换回 a[i]
        sort(a, low, i - 1); // 对低子表进行递归排序
        sort(a, i + 1, hight); // 对高子表进行递归排序

    }

    public static void quickSort(int a[]) {
        sort(a, 0, a.length - 1);
    }

    public static void main(String[] args) {

        int a[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
        quickSort(a);
        System.out.println(Arrays.toString(a));
    }
}
